package chatserver.netio;


import chatserver.tools.ChatException;
import java.io.*;

public abstract class Message
        implements Cloneable {

    public Message() {
        this((byte) 0);
    }

    public Message(byte byte0) {
        this(byte0, new AttrList());
    }

    public Message(byte byte0, AttrList attrlist) {
        msgid = byte0;
        params = attrlist;
    }

    public Message(InputStream inputstream)
            throws ChatException, IOException {
        this(inputstream, 0x7fffffff);
    }

    public Message(InputStream inputstream, int i)
            throws ChatException, IOException {
        read(inputstream, i);
    }

    public void read(InputStream inputstream)
            throws ChatException, IOException {
        read(inputstream, 0x7fffffff);
    }

    public void read(InputStream inputstream, int i)
            throws ChatException, IOException {
        int j = inputstream.read();
        if (j == -1) {
            throw new EOFException();
        } else {
            msgid = (byte) j;
            params = new AttrList(getAttrProto(), inputstream, i - 1);
            return;
        }
    }

    public void write(OutputStream outputstream)
            throws ChatException, IOException {
        outputstream.write(msgid);
        params.write(outputstream);
    }

    public byte[] getByteCache(boolean flag)
            throws ChatException {
        if (!flag || bytes == null) {
            try {
                ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
                write(bytearrayoutputstream);
                bytes = bytearrayoutputstream.toByteArray();
            } catch (IOException ioexception) {
                throw new ChatException(ioexception.toString());
            }
        }
        return bytes;
    }

    public byte[] getByteCacheSafe(boolean flag) {
        if (!flag || bytes == null) {
            try {
                ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
                write(bytearrayoutputstream);
                bytes = bytearrayoutputstream.toByteArray();
            } catch (Exception exception) {
            }
        }
        return bytes;
    }

    public byte getId() {
        return msgid;
    }

    public AttrList getParams() {
        return params;
    }

    public Message(String as[], Reader reader)
            throws ChatException, IOException {
        char c;
        do {
            c = (char) reader.read();
            if (c == '\n') {
                throw new ChatException("no message name");
            }
        } while (Character.isWhitespace(c));
        String s = new String();
        s = (new StringBuilder(String.valueOf(s))).append(c).toString();
        do {
            reader.mark(1);
            c = (char) reader.read();
            if (!Character.isLetterOrDigit(c)) {
                break;
            }
            s = (new StringBuilder(String.valueOf(s))).append(c).toString();
        } while (true);
        reader.reset();
        for (msgid = 0; (msgid & 0xff) < as.length && !as[msgid & 0xff].equalsIgnoreCase(s); msgid++) {
        }
        if ((msgid & 0xff) == as.length) {
            try {
                msgid = (byte) Integer.parseInt(s);
            } catch (Exception exception) {
                throw new ChatException("unknown message name");
            }
        }
        params = new AttrList(getAttrProto(), reader);
        do {
            c = (char) reader.read();
            if (c == '\n') {
                return;
            }
        } while (Character.isWhitespace(c));
        throw new ChatException((new StringBuilder("invalid character '")).append(c).append("'").toString());
    }

    protected abstract Attr getAttrProto();

    public abstract String getName();

    @Override
    public abstract Object clone();

    public String getName(String as[]) {
        return (getId() & 0xff) >= as.length ? Integer.toString(getId() & 0xff) : as[getId() & 0xff];
    }

    public String toString(String s, String as[]) {
        return (new StringBuilder(String.valueOf(s))).append(getName(as)).append(" ").append(params.toString()).toString();
    }
    public static byte ESC_NONE = 0;
    public static byte ESC_HTML = 1;
    public static byte ESC_QUOTES = 2;
    public static byte ESC_URL = 4;
    public static byte ESC_NOFILTER = 8;
    static char hex[] = {
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        'a', 'b', 'c', 'd', 'e', 'f'
    };
    private byte msgid;
    private AttrList params;
    private byte bytes[];
    private static final char ESC = 37;
    public static final int MAXNEST = 10;
}
